<?php

//服务端返回数据格式
/*
   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
   <html>
       <head>
           <META NAME="MobilePayPlatform" CONTENT="amount=1&amt_type=RMB&bank_payurl=weixin://wxpay/bizpayurl?pr=MfufsFp&mer_date=20170830&mer_id=60000100&mer_priv=&order_id=493585&platDate=20170830&ret_code=0000&ret_msg=操作成功&sign_type=RSA&trade_state=WAIT_BUYER_PAY&version=4.0&sign=tHgG2DiuFlKc2ldVA/0KJ9iZSU9rRiebN0ogVQAO0AHijd+4uVwjrrIPIF+D12yrFTenrnycrAfPussrRl1UxXioxOHDISSuL6GcXjgp3VlhOB7vbYO+t1NC61tUj03C9AFXT0tq5XEhrSTtx2vjsXEaVIty2YQUjbml6Ux4LqY=">
       </head>
       <body>
       </body>
   </html>
*/

//http://www.3mu.me/php%E7%9A%84curl%E9%80%89%E9%A1%B9curlopt_ssl_verifypeer%E8%AF%A6%E8%A7%A3/

// cli 模式执行 目录改为文件所在目录
chdir(dirname(__FILE__));

require_once ("../api/common.php");

class UmfHttp {
    /**
     * @param string $urlStr 向服务端发起GET请求的url字符串
     */
    public function httpGet($urlStr=""){
        $log = new Logger();
        $log->logInfo("[UMF SDK]本次请求的URL地址 ".$urlStr);
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $urlStr);
        // 对认证证书来源的检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        // 从证书中检查SSL加密算法是否存在
        //curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        // 设置超时限制防止死循环
        curl_setopt($ch, CURLOPT_TIMEOUT,90);
        curl_setopt($ch, CURLOPT_HEADER, 0);
        $output = curl_exec($ch);
        if (curl_errno($ch)){
            $log->logInfo('[UMF SDK 子商户入网]网络请求失败,错误信息 = '.curl_error($ch));
            $log->logInfo("--------------------log end---------------------");
            die('[UMF SDK]网络请求失败,错误信息 = '.curl_error($ch));//捕抓异常
        }
        curl_close($ch);
        $log->logInfo("[UMF SDK]本次请求原始响应数据 ".$output);

        //对账直接返回
        $searchStr = strstr($urlStr,"service=download_settle_file");
        if(!empty($searchStr)){
            $log->logInfo("[UMF SDK]对账接口返回原始响应数据 ".$output);
            return $output;
        }

        // 解析HTML返回 CONTENT
        $contentStr = self::parseHTMLStr($output);
        $contentArr = explode('&',$contentStr);
        $response = array();
        for($i=0;$i<count($contentArr);$i++){
            $str = $contentArr[$i];
            $arr = explode('=',$str,2);
            $response[$arr[0]] = $arr[1];
        }
        $log->logInfo("[UMF SDK]本次请求处理后返回的响应数据 ".$log->logArrToStr($response));
        $log->logInfo("--------------------log end---------------------");
        return $response;
    }

    /**
     * @param string $urlStr 向服务端发起POST请求的url字符串
     * @param $map
     */
    public function httpPost($urlStr="", $map){
        // 启动一个CURL会话
        $ch = curl_init();
        // 要访问的地址
        curl_setopt($ch, CURLOPT_URL, $urlStr);
        // 对认证证书来源的检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        // 从证书中检查SSL加密算法是否存在
        //curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
        // 模拟用户使用的浏览器
        //curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
        // 发送一个常规的Post请求
        curl_setopt($ch, CURLOPT_POST, 1);
        // Post提交的数据包
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($map->getInnerArr()));
        // 获取的信息以文件流的形式返回
        curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
        // 使用自动跳转
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION,1);
        // 自动设置Referer
        curl_setopt($ch, CURLOPT_AUTOREFERER,1);
        curl_setopt($ch, CURLOPT_MAXREDIRS,4);
        curl_setopt($ch, CURLOPT_ENCODING,""); //必须解压缩防止乱码
        // 设置超时限制防止死循环
        curl_setopt($ch, CURLOPT_TIMEOUT,90);
        // 显示返回的Header区域内容
        curl_setopt($ch, CURLOPT_HEADER, 0);
        $output = curl_exec($ch);
        $log = new Logger();
        if (curl_errno($ch)){
            $log->logInfo('[UMF SDK 子商户入网]网络请求失败,错误信息 = '.curl_error($ch));
            $log->logInfo("--------------------log end---------------------");
            die('[UMF SDK]网络请求失败,错误信息 = '.curl_error($ch));//捕抓异常
        }
        curl_close($ch);
        $log->logInfo("[UMF SDK]本次请求原始响应数据 ".$output);

        //对账直接返回
        if($map->get("service") == "download_settle_file"){
            $log->logInfo("[UMF SDK]对账接口返回原始响应数据 ".$output);
            return $output;
        }

        // 解析HTML返回 CONTENT
        $contentStr = self::parseHTMLStr($output);
        $contentArr = explode('&',$contentStr);
        $response = array();
        for($i=0;$i<count($contentArr);$i++){
            $str = $contentArr[$i];
            $arr = explode('=',$str,2);
            if($arr[0]=='sign' || $arr[0]=='sign_type' || $arr[0]=='version'){
                continue;
            }
            $response[$arr[0]] = $arr[1];
        }
        $log->logInfo("[UMF SDK]本次请求处理后返回的响应数据 ".$log->logArrToStr($response));
        $log->logInfo("--------------------log end---------------------");
        return $response;
    }

    private function parseHTMLStr($htmlStr) {
        $content = '';
        if (!empty($htmlStr)) {
            // MobilePayPlatform
            preg_match('/<META\s+name="MobilePayPlatform"\s+content="([\w\W]*?)"/si', $htmlStr, $matches);
            if (!empty($matches[1])) {
                $content = $matches[1];
            }

            $resParamsArr = explode('&',$content);
            $plain = "";
            $sign = "";
            for($i=0;$i<count($resParamsArr);$i++){
                $str = $resParamsArr[$i];
                $arr = explode('=',$str,2);
                if($arr[0]=="sign_type"){
                    continue;
                }
                if($arr[0]=="sign"){
                    $sign = $arr[1];
                    continue;
                }
                $plain .= $resParamsArr[$i] . "&";
            }
            $plain = substr($plain,0,strlen($plain)-1);
            // 字符串的编码 从UTF-8 转到GBK
            $plain=iconv("UTF-8", "GBK", $plain);
            $verifyRet = SignUtil::verify($plain,$sign);
            if($verifyRet == true){
                //echo "[UMF SDK] 平台响应数据验签成功";
                return $content;
            }else{
                //die("[UMF SDK] 平台响应数据验证签名发生异常");
            }
        }
    }

/************************************************************/
//子商户入网部分
    public function httpRequestWithJson($urlStr="",$isPost=true,$jsonParam,$headers=array()){
        $log = new Logger();
        $log->logInfo("[UMF SDK 子商户入网]本次请求对应的URL " .$urlStr);
        $log->logInfo($isPost==true? "[UMF SDK 子商户入网]本次请求方式 post" : "[UMF SDK 子商户入网]本次请求方式 get");
        if(strpos($urlStr, UMF_RESTPAY_UPLOADCHILDFILE) !== false){
            //上传文件接口 由于文件的二进制数据过大 不写入log
        }else{
            $log->logInfo("[UMF SDK 子商户入网]本次请求对应的json " .$jsonParam);
        }
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $urlStr);
        curl_setopt($ch, CURLOPT_POST, $isPost);
        curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
        if($jsonParam != ""){
            curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonParam);
        }
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
        curl_setopt($ch, CURLOPT_TIMEOUT, 90);
        $response = curl_exec($ch);
        if (curl_errno($ch)){
            $log->logInfo('[UMF SDK 子商户入网]网络请求失败,错误信息 = '.curl_error($ch));
            $log->logInfo("--------------------log end---------------------");
            die('[UMF SDK 子商户入网]网络请求失败,错误信息 = '.curl_error($ch));//捕抓异常
        }
        curl_close($ch);
        // 验签
        $arr = explode('&',$response,2);
        if(count($arr) == 2){
            $resPlain = $arr[0];
            $resSign = $arr[1];
            $verifyRet = SignUtil::verify256($resPlain,$resSign);
            if($verifyRet == true){
                $log->logInfo("[UMF SDK 子商户入网]本次请求原始响应数据 ".$response);
                $log->logInfo("--------------------log end---------------------");
                return json_decode($resPlain);
            }else{
                die("[UMF SDK 子商户入网] 平台响应数据验证签名发生异常");
            }
        }
        elseif($urlStr==UMF_RESTPAY_AUTHORIZE) { // 获取token接口没有sign字段
            return json_decode($response);
        }
    }

}

?>

